﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2015-04-26 19:39:54Z</CreationDate>
</File>
*/
#endregion

using System;

using Windows.Phone.Devices.Power;

using Microsoft.Phone.Info;

namespace Outcoder.Devices.Power
{
	public class PowerService : IPowerService
	{
		DevicePowerSource lastKnowPowerSource;
		bool subscribed;

		public PowerService()
		{
			var messenger = Dependency.Resolve<IMessenger>();
			messenger.Subscribe(this);
		}

		public void StartMonitoring()
		{
			var battery = Battery.GetDefault();
			if (battery != null)
			{
				battery.RemainingChargePercentChanged -= HandleRemainingChargePercentChanged;
				battery.RemainingChargePercentChanged += HandleRemainingChargePercentChanged;
			}

			lastKnowPowerSource = PowerSource;

			if (subscribed)
			{
				/* Weird implementation of PowerSourceChanged event means 
				 * that a NullReferenceException is raised if you haven't subscribed already. */
				DeviceStatus.PowerSourceChanged -= HandlePowerSourceChanged;
			}

			DeviceStatus.PowerSourceChanged += HandlePowerSourceChanged;

			subscribed = true;
		}

		public void StopMonitoring()
		{
			var battery = Battery.GetDefault();
			if (battery != null)
			{
				battery.RemainingChargePercentChanged -= HandleRemainingChargePercentChanged;
			}

			if (subscribed)
			{
				DeviceStatus.PowerSourceChanged -= HandlePowerSourceChanged;
			}

			subscribed = false;
		}

		async void HandlePowerSourceChanged(object sender, EventArgs eventArgs)
		{
			IMessenger messenger;
			if (Dependency.TryResolve<IMessenger>(out messenger))
			{
				var temp = lastKnowPowerSource;
				lastKnowPowerSource = PowerSource;

				await messenger.Publish(new PowerSourceChangeEvent(this, temp, lastKnowPowerSource));
			}
		}

		async void HandleRemainingChargePercentChanged(object sender, object o)
		{
			IMessenger messenger;
			if (Dependency.TryResolve<IMessenger>(out messenger))
			{
				var args = new RemainingBatteryChargeEvent(this, RemainingBatteryChargePercent, RemainingBatteryDischargeTime);
				await messenger.Publish(args);
			}
		}

		public int RemainingBatteryChargePercent
		{
			get
			{
				var battery = Battery.GetDefault();
				var result = battery.RemainingChargePercent;
				return result;
			}
		}

		public TimeSpan RemainingBatteryDischargeTime
		{
			get
			{
				var battery = Battery.GetDefault();
				var result = battery.RemainingDischargeTime;
				return result;
			}
		}

		public DevicePowerSource PowerSource
		{
			get
			{
				return DeviceStatus.PowerSource == Microsoft.Phone.Info.PowerSource.External 
					? DevicePowerSource.External 
					: DevicePowerSource.Battery;
			}
		}
	}
}
